using Microsoft.Extensions.Logging;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Forms;
using DesktopHelper.Data;
using DesktopHelper.Models;
using System.Threading.Tasks;

namespace DesktopHelper.Services
{
    public class ClipboardService
    {
        private readonly ILogger<ClipboardService> _logger;
        private readonly DatabaseService _databaseService;
        private HwndSource? _hwndSource;
        private bool _isMonitoring;

        // Windows API 常量
        private const int WM_CLIPBOARDUPDATE = 0x031D;
        
        // 剪贴板项目添加事件
        public event EventHandler<ClipboardItem>? ClipboardItemAdded;

        public ClipboardService(ILogger<ClipboardService> logger, DatabaseService databaseService)
        {
            _logger = logger;
            _databaseService = databaseService;
        }

        public void StartMonitoring()
        {
            if (_isMonitoring) return;

            try
            {
                // 确保在UI线程上创建HwndSource
                System.Windows.Application.Current.Dispatcher.Invoke(() =>
                {
                    // 创建HwndSource参数
                    var parameters = new HwndSourceParameters("ClipboardListener")
                    {
                        Width = 0,
                        Height = 0,
                        WindowStyle = 0,
                        ExtendedWindowStyle = 0,
                        WindowClassStyle = 0,
                        UsesPerPixelOpacity = false
                    };

                    // 创建HwndSource
                    _hwndSource = new HwndSource(parameters);
                    if (_hwndSource == null || _hwndSource.Handle == IntPtr.Zero)
                    {
                        _logger.LogError("无法创建HwndSource");
                        return;
                    }
                    
                    _hwndSource.AddHook(WndProc);

                    // 注册剪贴板监听
                    if (NativeMethods.AddClipboardFormatListener(_hwndSource.Handle))
                    {
                        _isMonitoring = true;
                        _logger.LogInformation("剪贴板监听已启动");
                    }
                    else
                    {
                        _logger.LogError("无法注册剪贴板监听");
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "启动剪贴板监听失败");
                throw; // 重新抛出异常以便上层捕获
            }
        }

        public void StopMonitoring()
        {
            if (!_isMonitoring) return;

            try
            {
                if (_hwndSource != null)
                {
                    NativeMethods.RemoveClipboardFormatListener(_hwndSource.Handle);
                    _hwndSource.RemoveHook(WndProc);
                    _hwndSource.Dispose();
                    _hwndSource = null;
                }

                _isMonitoring = false;
                _logger.LogInformation("剪贴板监听已停止");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "停止剪贴板监听失败");
            }
        }

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_CLIPBOARDUPDATE)
            {
                _ = Task.Run(ProcessClipboardChangedAsync);
            }
            return IntPtr.Zero;
        }

        private async Task ProcessClipboardChangedAsync()
        {
            try
            {
                await System.Windows.Application.Current.Dispatcher.InvokeAsync(async () =>
                {
                    var dataObject = System.Windows.Clipboard.GetDataObject();
                    if (dataObject == null) return;

                    ClipboardItem? item = null;

                    // 处理文本数据
                    if (dataObject.GetDataPresent(System.Windows.DataFormats.UnicodeText))
                    {
                        var text = (string)dataObject.GetData(System.Windows.DataFormats.UnicodeText);
                        if (!string.IsNullOrWhiteSpace(text))
                        {
                            item = new ClipboardItem
                            {
                                Type = ClipboardDataType.Text,
                                Content = text,
                                CreateTime = DateTime.Now,
                                Hash = ComputeHash(text)
                            };
                        }
                    }
                    // 处理图片数据
                    else if (dataObject.GetDataPresent(System.Windows.DataFormats.Bitmap))
                    {
                        var image = (System.Windows.Media.Imaging.BitmapSource)dataObject.GetData(System.Windows.DataFormats.Bitmap);
                        if (image != null)
                        {
                            var imageData = BitmapSourceToBytes(image);
                            var thumbnail = CreateThumbnail(imageData);

                            item = new ClipboardItem
                            {
                                Type = ClipboardDataType.Image,
                                ImageData = imageData,
                                Thumbnail = thumbnail,
                                CreateTime = DateTime.Now,
                                Hash = ComputeHash(imageData)
                            };
                        }
                    }
                    // 处理文件数据
                    else if (dataObject.GetDataPresent(System.Windows.DataFormats.FileDrop))
                    {
                        var files = (string[])dataObject.GetData(System.Windows.DataFormats.FileDrop);
                        if (files != null && files.Length > 0)
                        {
                            var filesText = string.Join(";", files);
                            item = new ClipboardItem
                            {
                                Type = ClipboardDataType.File,
                                Content = filesText,
                                CreateTime = DateTime.Now,
                                Hash = ComputeHash(filesText)
                            };
                        }
                    }

                    if (item != null)
                    {
                        await _databaseService.InsertClipboardItemAsync(item);
                        _logger.LogDebug("保存剪贴板项目: {Type}", item.Type);
                        
                        // 触发事件通知界面更新
                        ClipboardItemAdded?.Invoke(this, item);
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理剪贴板变化失败");
            }
        }

        private string ComputeHash(string input)
        {
            using var sha256 = SHA256.Create();
            var bytes = Encoding.UTF8.GetBytes(input);
            var hash = sha256.ComputeHash(bytes);
            return Convert.ToBase64String(hash);
        }

        private string ComputeHash(byte[] input)
        {
            using var sha256 = SHA256.Create();
            var hash = sha256.ComputeHash(input);
            return Convert.ToBase64String(hash);
        }

        private byte[] BitmapSourceToBytes(System.Windows.Media.Imaging.BitmapSource bitmapSource)
        {
            var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
            encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bitmapSource));

            using var stream = new MemoryStream();
            encoder.Save(stream);
            return stream.ToArray();
        }

        private byte[] CreateThumbnail(byte[] imageData)
        {
            try
            {
                using var originalStream = new MemoryStream(imageData);
                using var originalImage = Image.FromStream(originalStream);
                
                // 创建缩略图 (最大100x100)
                var thumbnailSize = CalculateThumbnailSize(originalImage.Size, new System.Drawing.Size(100, 100));
                using var thumbnail = new Bitmap(thumbnailSize.Width, thumbnailSize.Height);
                using var graphics = Graphics.FromImage(thumbnail);
                
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.DrawImage(originalImage, 0, 0, thumbnailSize.Width, thumbnailSize.Height);
                
                using var thumbnailStream = new MemoryStream();
                thumbnail.Save(thumbnailStream, System.Drawing.Imaging.ImageFormat.Png);
                return thumbnailStream.ToArray();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建缩略图失败");
                return Array.Empty<byte>();
            }
        }

        private System.Drawing.Size CalculateThumbnailSize(System.Drawing.Size originalSize, System.Drawing.Size maxSize)
        {
            var ratioX = (double)maxSize.Width / originalSize.Width;
            var ratioY = (double)maxSize.Height / originalSize.Height;
            var ratio = Math.Min(ratioX, ratioY);

            return new System.Drawing.Size(
                (int)(originalSize.Width * ratio),
                (int)(originalSize.Height * ratio)
            );
        }
    }

    // Windows API 声明
    internal static partial class NativeMethods
    {
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        internal static extern bool AddClipboardFormatListener(IntPtr hwnd);

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        internal static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
    }
}